includedir := include
srcdir := src

VPATH = $(LLVM_GCC_INCLUDE);$(LLVM_GCC_INCLUDE)/c++/$(LLVM_GCC_VERSION);$(LLVM_GCC_INCLUDE)/c++/$(LLVM_GCC_VERSION)/backward
EMPTY :=
VPATH_INCLUDE_ARGS := $(addprefix -I ,$(subst ;,$(EMPTY) $(EMPTY),$(VPATH)))

vpath %.exe $(bindir)
vpath %.h $(includedir)
vpath %.o $(libdir)
vpath %.a $(libdir)
vpath %.s $(srcdir)
vpath %.cpp $(srcdir)

.PRECIOUS: %.o 
.PHONY: all
.PHONY: debug
.PHONY: clean

#Dependencies
OBJECTS := main.o

main.cpp: stdio.h stdlib.h string.h pthread.h pt_errors.h windows.h

#Goals
all: $(PROJ_NAME).exe
debug: $(PROJ_NAME).exe
clean:
	cd $(subst /,\,$(CWD))
	del $(libdir)\*.o
	del $(srcdir)\*.s
	del $(bindir)\*.exe

#Pattern rules for building in LLVM and adding debug symbols via GCC 
ifeq ($(MAKECMDGOALS),debug)

bindir := bin/debug
libdir := lib/debug

$(PROJ_NAME).exe: $(OBJECTS)
	llvm-g++ -ggdb $(addprefix $(libdir)/,$(<F)) -o $(bindir)/$@ -lpthread
	
%.o: %.cpp 
	llvm-g++ -Wall -c -ggdb ${CWD}/$(srcdir)/$(<F) -o $(libdir)/$@ $(VPATH_INCLUDE_ARGS) -I $(CWD)/$(includedir)
else

bindir := bin/release
libdir := lib/release

$(PROJ_NAME).exe: $(PROJ_NAME).s 
	llvm-g++ $(srcdir)/$(<F) -o $(bindir)/$@ $(VPATH_INCLUDE_ARGS) -lpthread
	
$(PROJ_NAME).o: $(OBJECTS)
	llvm-link $(addprefix $(libdir)/,$(+F)) -o $(libdir)/$@ -f
	
%.o: %.cpp
	llvm-g++ -Wall -O3 -emit-llvm $< -c -o $(libdir)/$@ $(VPATH_INCLUDE_ARGS) -I $(CWD)/$(includedir)

%.s: %.o
	llc $(libdir)/$< -o $(srcdir)/$@ -f
endif